/*!
  @file transporter.h
  @brief Brief Description
  @author Kyohei Otsu <kyon@ac.jaxa.jp>
  @date April, 2013
*/

#ifndef _TRANSPORTER_H_
#define _TRANSPORTER_H_

#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

#include <vector>
#include <string>
#include <tr1/memory>

#include "net/data_handler.h"

namespace net
{

//! class description 
class Transporter
{
 public:

  typedef std::tr1::shared_ptr<Transporter> Ptr;

  //! Constructor
  Transporter() : server_running_(false), sock_(-1), port_(1409) { }

  //! Destructor
  ~Transporter() { stopServer(); }


  //-- COMMON ------------------------------------------------
  
  //! set server address and port
  inline void setServerInfo(const std::string &ipaddr, const short port)
  {
    ipaddr_ = ipaddr;
    port_ = port;
  }
  
  //! kill all connections
  void shutdownAllConnections();
 
  
  //-- SERVER ------------------------------------------------
  
  //! start server
  int startServer();
  inline int startServer_(const short port)
  {
    setServerInfo("", port);
    return startServer();
  }
  
  //! close socket
  void stopServer();
  
  //! wait connection from client while server_running_
  void waitConnection();


  //-- CLIENT ------------------------------------------------
  //! connect to server
  void connectToServer();
  inline void connectToServer_(const std::string &ipaddr, const short port)
  {
    setServerInfo(ipaddr, port);
    connectToServer();
  }


  const std::string& ipaddr() const { return ipaddr_; }
  void set_ipaddr(const std::string &ipaddr) { ipaddr_ = ipaddr; }

  short port() const { return port_; }
  void set_port(const short port) { port_ = port; }

 private:

  typedef unsigned char uchar;


  //! true if the server is running
  bool server_running_;

  //! socket
  int sock_;

  //! ip address
  std::string ipaddr_;

  //! port
  short port_;

  struct sockaddr_in addr_; //!< address struct

  //! file pointers
  std::vector<FILE*> file_ptrs_;

  //! data handlers
  std::vector<DataHandler::Ptr> data_handlers_;

};

} // end of namespace

#endif
